#ifndef __BITSET__
#define __BITSET__
#include <vector>
#include <tr1/functional>

//if the invorement is working in 64 bit, need to define Word64

    typedef
    #ifndef  Word64
        unsigned   int
    #else
        unsigned long  int
    #endif  //Word32
    Word;



/******************************************************************************/
/**                     define class BitSet                                  **/
/******************************************************************************/

class BitSet
{

    typedef std::vector<Word>::iterator BitIter;

    typedef Word (BitSet::*DoFunc)(Word _this,Word _other);


    public:
        class BitRef;

        //BitSet(size_t   _size); disabled
        //~BitSet();    supply by compiler
         //BitSet(const BitSet& _other); supply by compiler
        explicit BitSet(size_t   _size); //ctor BitSet with size_t

        BitSet  operator=( BitSet& _other) ;
        BitSet  operator<<(size_t   _offset);
        BitSet  operator>>(size_t   _offset);
        BitSet  operator~();
        BitSet  operator&(const BitSet& _other);
        BitSet  operator|(const BitSet& _other);
        BitSet  operator^(const BitSet& _other);
        BitRef  operator[](size_t   _index);
        //bool    operator[](size_t   _index)const;

        void    Set(size_t  _index,bool _value);
        bool    Get(size_t  _index)const ;

        void    Print();

    private:


        #ifndef  Word64
            const static Word mask = 0xFFFFFFFF;
        #else
            const static Word mask = 0xFFFFFFFFFFFFFFFF;
        #endif
        const static size_t BitsInWord = sizeof(Word)*8;

        inline  size_t  CalcVecSize(size_t  _bits);//calc words number
        std::vector<Word>  m_bitSet;
        size_t             m_size;

        void Bzero();//init bit set to zero
        bool ShiftBoundChekout(size_t _size);//chek if shift is 0 or bigger then bitset size

        //do operation on the bit set,stops when one of bits set reach end
        BitSet DoBitSetOpeation( BitSet& _other,DoFunc _func);

        Word    DoAssign(Word& _this,Word& _other);
        Word    DoABitWiseAnd(Word& _this,Word& _other);
        Word    DoABitWiseOr(Word& _this,Word& _other);
        Word    DoABitWiseXor(Word& _this,Word& _other);


};


/******************************************************************************/
/**                     define class BitRef                                  **/
/******************************************************************************/

class   BitSet::BitRef
{
    public:

        operator  bool();

        BitRef&  operator=(bool  _to);
        BitRef&  operator=(const BitRef&  _to);




    private:
        BitRef(const BitRef& _other);


        friend  BitRef  BitSet::operator[](size_t   _index);
        BitRef(BitSet& _bitSet,size_t _index);

        BitSet& m_bitSet;
        size_t  m_index;

};

#endif // __BITSET__
